<template>
  <div>
    <Empty
      v-if="!selectedRole"
      :description="$t('daprplus.auth.roleAuthorize.selectTip')"
    />
    <div v-else>
      <DaprPlusTable
        :table-title="`${$t('daprplus.auth.roleAuthorize.list')} - ${selectedRole.name}`"
        :entity="entity"
        :show-search-form="true"
        :grid-options="gridOptions"
        :form-options="formOptions"
        :query-api="(query) => getRoleResourcePageApi(query, store.service)"
        :grid-events="gridEvents"
        @update:grid-api="onGridApiUpdate"
      >
        <template #extra-tools>
          <AccessControl :codes="['RoleResource:Set']" type="code">
            <Button class="mr-1" @click="handleAuthorize">
              <template #icon><KeyOutlined /></template>
              {{ $t('daprplus.auth.role.auth') }}
            </Button>
          </AccessControl>
        </template>
        <template #operations="{ row }">
          <div class="operations-container">
            <Tag
              v-for="op in row.operations"
              :key="op"
              :color="
                store.getResourceOperationColor(op, row.allowedOperations)
              "
              class="operation-tag"
            >
              {{ store.getResourceOperationLabel(op, row.allowedOperations) }}
            </Tag>
            <span v-if="!row.operations?.length" class="no-operations">{{
              $t('daprplus.auth.resource.noOperationsShort')
            }}</span>
          </div>
        </template>
        <template #expand_content="{ row }">
          <div class="filter-group-editor">
            <Card :title="`${row.resourceName} 过滤条件编辑`" :bordered="false">
              <!-- 操作选择器 -->
              <div class="mb-4">
                <div class="operation-selector">
                  <span class="mr-2">选择操作：</span>
                  <RadioGroup
                    :value="
                      row.id
                        ? store.selectedOperation[String(row.id)]
                        : undefined
                    "
                    @update:value="
                      (val) =>
                        row.id &&
                        (store.selectedOperation[String(row.id)] = val)
                    "
                    button-style="solid"
                  >
                    <RadioButton
                      v-for="op in row.operations"
                      :key="op"
                      :value="op"
                      :disabled="!row.operations?.length"
                    >
                      <Tag
                        :color="
                          store.getResourceOperationColor(
                            op,
                            row.allowedOperations,
                          )
                        "
                        class="operation-tag"
                      >
                        {{
                          store.getResourceOperationLabel(
                            op,
                            row.allowedOperations,
                          )
                        }}
                      </Tag>
                    </RadioButton>
                  </RadioGroup>
                </div>
              </div>

              <!-- 过滤条件配置 -->
              <div
                v-if="
                  row.id &&
                  store.selectedOperation[String(row.id)] !== undefined &&
                  row.operations?.length
                "
              >
                <FilterGroupConfig
                  :entity-metadata="row.entityMetadata"
                  :modelValue="
                    store.getOperationFilterGroup(
                      String(row.id),
                      store.selectedOperation[String(row.id)] || '',
                    )
                  "
                  @update:modelValue="
                    (val) => {
                      const operation = store.selectedOperation[String(row.id)];
                      if (operation) {
                        store.updateFilterGroup(String(row.id), operation, val);
                      }
                    }
                  "
                />
              </div>
              <Empty v-else description="请先选择一个操作" />

              <div class="mt-4 text-right">
                <Button
                  type="primary"
                  @click="store.saveFilterGroup(row)"
                  :disabled="
                    !hasAccessByCodes(['RoleResource:SetFilterGroups'])
                  "
                  >保存过滤条件</Button
                >
              </div>
            </Card>
          </div>
        </template>
      </DaprPlusTable>
    </div>

    <!-- 角色授权抽屉 -->
    <RoleAuthorizeDrawer
      v-model:open="store.roleAuthorizeOpen"
      :role="selectedRole"
      @update:open="handleDrawerOpenChange"
    />
  </div>
</template>

<script lang="ts" setup>
import { defineProps, defineEmits, watch } from 'vue';
import {
  Empty,
  Button,
  Tag,
  Card,
  RadioGroup,
  RadioButton,
} from 'ant-design-vue';
import { KeyOutlined } from '@ant-design/icons-vue';
import {
  DaprPlusTable,
  RoleAuthorizeDrawer,
  FilterGroupConfig,
} from '#/components/daprplus';
import {
  getRoleResourcePageApi,
  type RoleResourceOutDto,
} from '#/api/daprplus/auth/role-authorize';
import {
  createBooleanColumn,
  buildPageQuery,
  type EntityInfo,
} from '#/utils/daprplus';
import type {
  ExtendedVxeGridApi,
  VxeGridListeners,
  VxeTableGridOptions,
} from '#/adapter/vxe-table';
import type { VbenFormProps } from '#/adapter/form';
import { useRoleAuthorizeStore } from '#/store/daprplus/role-authorize';
import { serviceInfoDict } from '#/utils/daprplus/constants';
import type { ServiceName } from '#/api/daprplus/auth/resource';
import { $t } from '#/locales';
import { AccessControl, useAccess } from '@vben/access';

const props = defineProps<{
  selectedRole: { id: string; name: string } | null;
}>();

const emit = defineEmits<{
  (e: 'update:gridApi', api: ExtendedVxeGridApi): void;
}>();

const entity: EntityInfo = {
  code: 'RoleResource',
  display: $t('daprplus.auth.roleResource.title'),
};

const { hasAccessByCodes } = useAccess();

// 使用 store
const store = useRoleAuthorizeStore();

// 事件处理函数
const handleAuthorize = () =>
  props.selectedRole && (store.roleAuthorizeOpen = true);

let gridApi: ExtendedVxeGridApi;
function onGridApiUpdate(api: ExtendedVxeGridApi) {
  gridApi = api;
  emit('update:gridApi', api);
}

const gridEvents: VxeGridListeners<RoleResourceOutDto> = {
  toggleRowExpand: ({ row }) => {
    store.initRowFilterGroup(row);
  },
};

function handleDrawerOpenChange(open: boolean) {
  store.roleAuthorizeOpen = open;
  if (!open && gridApi) gridApi.query();
}

// 表单配置
const formOptions: VbenFormProps = {
  collapsed: false,
  schema: [
    {
      component: 'RadioGroup',
      label: '服务名称',
      fieldName: 'serviceName',
      defaultValue: 'IdentityApi',
      componentProps: {
        options: Object.entries(serviceInfoDict).map(([key, info]) => ({
          label: info.label,
          value: key as ServiceName,
        })),
        onChange: (value: any) => {
          const actualValue =
            typeof value === 'object' && value !== null && 'target' in value
              ? (value.target as any).value
              : value;

          if (
            typeof actualValue === 'string' &&
            ['IdentityApi', 'SoftwaresApi', 'GamesApi'].includes(actualValue)
          ) {
            store.selectedService = actualValue as ServiceName;
          }
        },
      },
    },
  ],
  showCollapseButton: true,
  submitOnChange: true,
};

// 表格配置
const gridOptions: VxeTableGridOptions<RoleResourceOutDto> = {
  columns: [
    { type: 'checkbox', width: 40 },
    { type: 'expand', width: 80, slots: { content: 'expand_content' } },
    { field: 'id', title: '编号', sortable: true, width: 130 },
    {
      field: 'resourceName',
      title: '资源',
      sortable: true,
      align: 'left',
      formatter: ({ cellValue, row }) => `${cellValue} [${row.resourceCode}]`,
    },
    {
      field: 'operations',
      title: '操作权限',
      slots: { default: 'operations' },
    },
    {
      field: 'createdTime',
      title: '创建时间',
      width: 150,
      formatter: 'formatDateTime',
    },
    createBooleanColumn('isLocked', '已锁定'),
  ],
  proxyConfig: {
    ajax: {
      query: async ({ page, sort, sorts }, formValues) => {
        const { serviceName, ...restFormValues } = formValues || {};
        const query = buildPageQuery(page, sorts || sort, restFormValues);

        if (props.selectedRole) {
          query.filterGroup.rules.push({
            field: 'roleId',
            value: props.selectedRole.id,
          });
        }
        return await getRoleResourcePageApi(query, store.service);
      },
    },
  },
};

// 监听选中的角色变化，清空状态
watch(
  () => props.selectedRole,
  () => {
    store.resetState();
    if (gridApi) gridApi.query();
  },
);
</script>

<style scoped>
.operations-container {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
}

.operation-tag {
  margin-right: 0;
  transition: all 0.3s;
}

.operation-tag:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.no-operations {
  color: #999;
  font-style: italic;
  font-size: 12px;
}

.filter-group-editor {
  padding: 16px;
  background-color: #f5f5f5;
}

.operation-selector {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
</style>
